home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gas_251.zip / bin_251 / opcodes / sh-dis.c < prev    next >
C/C++ Source or Header  |  1994-05-07  |  5KB  |  239 lines

  1. /* Disassemble h8500 instructions.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #define STATIC_TABLE
  20. #define DEFINE_TABLE
  21.  
  22. #include "sh-opc.h"
  23. #include "dis-asm.h"
  24.  
  25.  
  26. int 
  27. print_insn_sh(memaddr, info)
  28.      bfd_vma memaddr;
  29.      struct disassemble_info *info;
  30. {
  31.   fprintf_ftype fprintf = info->fprintf_func;
  32.   void *stream = info->stream;
  33.   unsigned  char insn[2];
  34.   unsigned  char nibs[4];
  35.   int status;
  36.   int relmask = ~0;
  37.   sh_opcode_info *op;
  38.  
  39.   int dslot = 0;
  40.   
  41.   status = info->read_memory_func(memaddr, insn, 2, info);
  42.  
  43.   if (status != 0) 
  44.     {
  45.       info->memory_error_func(status, memaddr, info);
  46.       return -1;
  47.     }
  48.  
  49.   nibs[0] = (insn[0] >> 4) & 0xf;
  50.   nibs[1] = insn[0] & 0xf;
  51.  
  52.   nibs[2] = (insn[1] >> 4) & 0xf;
  53.   nibs[3] = insn[1] & 0xf;
  54.  
  55.   for (op = sh_table; op->name; op++) 
  56.     {
  57.       int n;
  58.       int imm;
  59.       int rn;
  60.       int rm;
  61.       for (n = 0; n < 4; n++) {
  62.     int i = op->nibbles[n];
  63.     if (i < 16) 
  64.       {
  65.         if (nibs[n] == i) continue;
  66.         goto fail;
  67.       }
  68.     switch (i)
  69.       {
  70.       case BRANCH_8:
  71.         imm = (nibs[2] << 4) | (nibs[3]);      
  72.         if (imm & 0x80)
  73.           imm |= ~0xff;
  74.         imm = ((char)imm) * 2 + 4 ;
  75.         goto ok;
  76.  
  77.       case BRANCH_12:
  78.         imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
  79.         if (imm & 0x800)
  80.           imm |= ~0xfff;
  81.         imm = imm * 2 + 4;
  82.         goto ok;
  83.       case IMM_4:
  84.         imm = nibs[3];
  85.         goto ok;
  86.       case IMM_4BY2:
  87.         imm = nibs[3] <<1;
  88.         goto ok;
  89.       case IMM_4BY4:
  90.         imm = nibs[3] <<2;
  91.         goto ok;
  92.  
  93.         
  94.       case IMM_8:
  95.         imm = (nibs[2] << 4) | nibs[3];
  96.         goto ok;
  97.       case PCRELIMM_8BY2:
  98.         imm = ((nibs[2] << 4) | nibs[3]) <<1;
  99.         relmask  = ~1;
  100.         
  101.         goto ok;
  102.  
  103.       case PCRELIMM_8BY4:
  104.         imm = ((nibs[2] << 4) | nibs[3]) <<2;
  105.         relmask  = ~3;        
  106.         goto ok;
  107.         
  108.       case IMM_8BY2:
  109.         imm = ((nibs[2] << 4) | nibs[3]) <<1;
  110.         goto ok;
  111.       case IMM_8BY4:
  112.         imm = ((nibs[2] << 4) | nibs[3]) <<2;
  113.         goto ok;
  114.       case DISP_8:
  115.         imm = (nibs[2] << 4) | (nibs[3]);      
  116.         goto ok;
  117.       case DISP_4:
  118.         imm = nibs[3];
  119.         goto ok;
  120.       case REG_N:
  121.         rn = nibs[n];
  122.         break;
  123.       case REG_M:
  124.         rm = nibs[n];
  125.         break;
  126.       default:
  127.         abort();
  128.       }
  129.  
  130.       }
  131.     ok:
  132.       fprintf(stream,"%s\t", op->name);
  133.       for (n = 0; n < 2 && op->arg[n] != A_END; n++) 
  134.     {
  135.       if (n && op->arg[1] != A_END)
  136.         fprintf(stream,",");
  137.       switch (op->arg[n]) 
  138.         {
  139.         case A_IMM:
  140.           fprintf(stream,"#%d", (char)(imm));
  141.           break;
  142.         case A_R0:
  143.           fprintf(stream,"r0");
  144.           break;
  145.         case A_REG_N:
  146.           fprintf(stream,"r%d", rn);
  147.           break;
  148.         case A_INC_N:
  149.           fprintf(stream,"@r%d+", rn);    
  150.           break;
  151.         case A_DEC_N:
  152.           fprintf(stream,"@-r%d", rn);    
  153.           break;
  154.         case A_IND_N:
  155.           fprintf(stream,"@r%d", rn);    
  156.           break;
  157.         case A_DISP_REG_N:
  158.           fprintf(stream,"@(%d,r%d)",imm, rn);    
  159.           break;
  160.         case A_REG_M:
  161.           fprintf(stream,"r%d", rm);
  162.           break;
  163.         case A_INC_M:
  164.           fprintf(stream,"@r%d+", rm);    
  165.           break;
  166.         case A_DEC_M:
  167.           fprintf(stream,"@-r%d", rm);    
  168.           break;
  169.         case A_IND_M:
  170.           fprintf(stream,"@r%d", rm);    
  171.           break;
  172.         case A_DISP_REG_M:
  173.           fprintf(stream,"@(%d,r%d)",imm, rm);    
  174.           break;
  175.         case A_DISP_PC:
  176.           fprintf(stream,"0x%0x", imm+ 4+(memaddr&relmask));
  177.           break;
  178.         case A_IND_R0_REG_N:
  179.           fprintf(stream,"@(r0,r%d)", rn);
  180.           break; 
  181.         case A_IND_R0_REG_M:
  182.           fprintf(stream,"@(r0,r%d)", rm);
  183.           break; 
  184.         case A_DISP_GBR:
  185.           fprintf(stream,"@(%d,gbr)",imm);
  186.           break;
  187.         case A_R0_GBR:
  188.           fprintf(stream,"@(r0,gbr)");
  189.           break;
  190.         case A_BDISP12:
  191.         case A_BDISP8:
  192.           fprintf(stream,"0x%x", imm + memaddr);    
  193.           break;
  194.         case A_SR:
  195.           fprintf(stream,"sr");
  196.           break;
  197.         case A_GBR:
  198.           fprintf(stream,"gbr");
  199.           break;
  200.         case A_VBR:
  201.           fprintf(stream,"vbr");
  202.           break;
  203.         case A_MACH:
  204.           fprintf(stream,"mach");
  205.           break;
  206.         case A_MACL:
  207.           fprintf(stream,"macl");
  208.           break;
  209.         case A_PR:
  210.           fprintf(stream,"pr");
  211.           break;
  212.         default:
  213.           abort();
  214.         }
  215.     
  216.     }
  217.       if (!info->flags &&
  218.       op->name[0] == 'j'
  219.       || (op->name[0] == 'b' && (op->name[1] == 'r' 
  220.                      || op->name[1] == 's'))
  221.       || (op->name[0] == 'r' && op->name[1] == 't')
  222.       || (op->name[0] == 'b' && op->name[2] == '.'))
  223.     {
  224.       info->flags = 1;
  225.       fprintf(stream,"\t(slot ");  print_insn_sh(memaddr +2, info);
  226.       info->flags = 0;
  227.       fprintf(stream,")");
  228.       return 4;
  229.     }
  230.       
  231.       return 2;
  232.     fail:
  233.       ;
  234.  
  235.     }
  236.   fprintf(stream,".word 0x%02x%02x", insn[0], insn[1]);
  237.   return 2;
  238. }
  239.